package org.bit.lesson07;

/**
 * 自定义阻塞队列
 */
public class MyBlockingQueue {
    // 定义数组存放数据
    private Integer[] elementData;
    // 定义头尾下标
    private volatile int head = 0;
    private volatile int tail = 0;
    // 定义数组中元素的个数
    private volatile int size = 0;

    // 构造方法
    public MyBlockingQueue(int capacity) {
        if (capacity <= 0) {
            throw new RuntimeException("队列容量必须大于0");
        }
        elementData = new Integer[capacity];
    }

    // 插入数据
    public void put(Integer value) throws InterruptedException {
        synchronized (this) {
            // 判断队列是否为空
            while (size >= elementData.length) {
                this.wait();
            }
            // 对尾插入元素
            elementData[tail] = value;
            // 移动队头下标
            tail++;
            if (tail >= elementData.length) {
                tail = 0;
            }
            // 元素个数+1
            size++;
            // 唤醒阻塞线程
            this.notifyAll();
        }
    }

    // 获取数据
    public synchronized Integer take() throws InterruptedException {
        // 判断队列是否为空
        while (size == 0) {
            this.wait();
        }
        Integer value = elementData[head];
        head++;
        if (head >= elementData.length) {
            head = 0;
        }
        size--;
        // 唤醒阻塞线程
        this.notifyAll();
        return value;
    }
}
